import dynamic from 'next/dynamic'
import Responsive from '@c/responsive'
import ProgramItem from '@c/sports/program-item'
import { useEffect, useState, useRef } from 'react'
import { SPORTS_PATHS, SPORT_INFO, HOT_RACE_ARR } from '@/constant'
import {
  getProject,
  getCompetition,
  getMatchListByTime,
  getEffectiveTime,
  getCompetitionDesc,
  getRaceUrlMap
} from '@/api/sports'
import styles from './index.module.scss'
import { useRouter } from 'next/router'
import cm from 'classnames'
import { TODAY } from '@/utils/date'
import { getShuffleHots, generateMapRace, findClosestNumber } from '@/utils/utils'
import { useShowLogin } from '@/utils/hooks'
import Link from 'next/link'
import last from 'lodash-es/last'
import head from 'lodash-es/head'
import scrollIntoViewIfNeeded from 'scroll-into-view-if-needed'

const Loading = dynamic(() => import('@c/loading'))
const Calendar = dynamic(() => import('@c/sports/calendar'))

const currDay = parseInt(TODAY())
const urlMatch = SPORT_INFO.reduce((final, target) => {
  final[target['name']] = target['url']
  return final
}, {})
export default function Sports(props) {
  const router = useRouter()
  const { project = [], currType, currTypeInfo, matchDate = [], urlMap, isFirstPath, shuffleHots, classify } = props
  const [classifyType, setClassifyType] = useState([]) //类目
  const [dateList, setDateList] = useState([]) //相关的又比赛的时间
  const [init, setInit] = useState(false)
  const allRaceArr = generateMapRace(project, urlMap)
  // 列表数据相关
  const [upScrollStatus, setUpScrollStatus] = useState(null)
  const [downScrollStatus, setDownScrollStatus] = useState(null)
  const [isDownEnd, setDownEnd] = useState(false)
  const [isUpEnd, setUpEnd] = useState(false)
  const [listData, setListData] = useState(matchDate) //匹配数据
  const [isLoadData, setIsLoadData] = useState(false)
  const [desc, setDesc] = useState('')
  const setShowLogin = useShowLogin()
  const [showRaceAll, setRaceALl] = useState(false)
  const [showPhoneDesc, setSHowPhoneDesc] = useState(false)
  //归位初始数据
  const backInitData = () => {
    setDesc('')
    setListData(matchDate)
    setUpEnd(false)
    setDownEnd(false)
  }
  // url变化更新数据 //

  // 获取赛事简介
  const getDesc = async id => {
    if (!id) {
      return
    }
    const res = await getCompetitionDesc(id)
    setDesc(res?.data?.description)
  }

  // 获取某个体育类目下全部赛事
  const getAllClassify = async id => {
    const res = await getCompetition({ id })
    setClassifyType([{ name: '全部', id: undefined }, res?.data?.competitionItem].flat(Infinity))
  }

  // 获取某个类目的比赛有效时间
  const getEffectDates = async ({ projectId, competitionId }) => {
    const params = {
      projectId: isFirstPath ? projectId : undefined,
      competitionId: isFirstPath ? undefined : competitionId,
      style: '0'
    }
    const res = await getEffectiveTime(params)
    setDateList(res?.data?.effectiveTimeList || [])
  }

  // 获取首次页面数据
  const getFisrtListData = async ({ projectId, competitionId }) => {
    if (!init) {
      return
    }
    const params = {
      projectId: isFirstPath ? projectId : undefined,
      competitionId: isFirstPath ? undefined : competitionId
    }
    const matchRes = await getMatchListByTime(params)
    setListData(matchRes?.data?.matchDate || [])
  }
  useEffect(() => {
    // 初始化一些参数
    backInitData()
    getFisrtListData(currTypeInfo)
    getAllClassify(currTypeInfo.projectId)
    getEffectDates(currTypeInfo)
    getDesc(currTypeInfo.competitionId)
  }, [router.asPath])

  // 上拉下滑更多
  const parentRef = useRef(null)
  useEffect(() => {
    setInit(true)
    const handleScroll = async () => {
      const parentElement = parentRef.current
      const scrollTop = parentElement.scrollTop
      const scrollHeight = parentElement.scrollHeight
      const clientHeight = parentElement.clientHeight
      // 判断是否下触底
      if (scrollTop + clientHeight >= scrollHeight) {
        setDownScrollStatus(new Date().valueOf())
      }

      // 判断是否上触底
      if (scrollTop <= 0) {
        setUpScrollStatus(new Date().valueOf())
      }
    }
    const parentElement = parentRef.current
    parentElement.addEventListener('scroll', handleScroll)
    return () => {
      sessionStorage.setItem('lastPage', true)
      parentElement.removeEventListener('scroll', handleScroll)
    }
  }, [])

  // 下滑触底加载更多
  useEffect(() => {
    if (!downScrollStatus || isDownEnd || !init || !listData.length) {
      return
    }
    let date = last(listData)?.date
    setIsLoadData(true)
    const params = {
      timeBorder: date,
      forward: 'down',
      competitionId: isFirstPath ? undefined : currTypeInfo.competitionId,
      projectId: isFirstPath ? currTypeInfo.projectId : undefined
    }
    getMatchListByTime(params).then(res => {
      const isEnd = !res.data?.matchDate?.length
      if (!isEnd) {
        let newData = [...listData, ...res.data.matchDate]
        setListData(newData)
      }
      setDownEnd(isEnd)
      setIsLoadData(false)
    })
  }, [downScrollStatus])
  // 上拉触顶加载更多

  // 滑动归位
  const scrollToPrevPosition = data => {
    if (!data.length) {
      return
    }
    const totalHeight = data.reduce((final, target) => {
      final += (target.matchList?.length || 0) * 84 + 56
      return final
    }, 0)
    setTimeout(() => {
      parentRef.current.scrollTo(0, totalHeight)
    }, 0)
  }
  useEffect(() => {
    if (!upScrollStatus || isUpEnd || !init || !listData.length) {
      return
    }
    setIsLoadData(true)
    let date = head(listData)?.date
    const params = {
      timeBorder: date,
      forward: 'up',
      competitionId: isFirstPath ? undefined : currTypeInfo.competitionId,
      projectId: isFirstPath ? currTypeInfo.projectId : undefined
    }
    getMatchListByTime(params).then(res => {
      const isEnd = !res.data?.matchDate?.length
      if (!isEnd) {
        const loadedData = res.data?.matchDate || []
        let newData = [...loadedData, ...listData]
        setListData(newData)
        scrollToPrevPosition(loadedData)
      }
      setUpEnd(isEnd)
      setIsLoadData(false)
    })
  }, [upScrollStatus])

  // 体育类目下分类切换
  const onSelectChange = async item => {
    const all = item.name == '全部'
    const getUrl = () => {
      if (all) {
        return urlMatch[currType]
      }
      return (urlMap.filter(child => child.competitionId == item.id).pop() || {})?.url
    }
    router.replace(`/sports/${getUrl()}`)
  }

  // 时间选择监听
  const dateChange = async e => {
    const params = {
      competitionId: isFirstPath ? undefined : currTypeInfo.competitionId,
      projectId: isFirstPath ? currTypeInfo.projectId : undefined,
      timeBorder: e.date
    }
    const matchRes = await getMatchListByTime(params)
    setListData(matchRes?.data?.matchDate || [])
    setUpEnd(false)
    setDownEnd(false)
  }

  // 更新时间限制
  const updateListData = (id, status) => {
    const newList = listData?.map(item => {
      item.matchList = item.matchList?.map(child => {
        if (child.matchID == id) {
          child.status = status
        }
        return child
      })
      return item
    })

    setListData(newList)
  }

  // 定位到当前最近日期节目单
  useEffect(() => {
    if (!matchDate?.length) {
      return
    }
    setTimeout(() => {
      const dateArr = matchDate.map(item => item.date)
      const currScrollId = findClosestNumber(dateArr, currDay)
      try {
        const el = document.querySelector(`#date-${currScrollId}`)
        const elContainer = parentRef?.current
        scrollIntoViewIfNeeded(el, {
          behavior: 'smooth',
          block: 'start',
          inline: 'nearest',
          boundary: elContainer
        })
      } catch (error) {}
    }, 50)
  }, [classify])

  // 注入stickyFill支持
  useEffect(() => {
    try {
      const StickyFill = require('stickyfill')()
      StickyFill.add(parentRef.current)
    } catch (error) {}
  }, [])
  return (
    <Responsive>
      <div className={styles.programContainer}>
        <div className={cm(styles.select, 'hideWhenPhone')}>
          <div className={styles.selectLeft}>
            <h1 className={styles.leftH1}>
              <span>{!isFirstPath ? currTypeInfo.competitionName : '全部'}</span>
              <img loading="lazy" src="/images/select.png" alt="选择" className={styles.img} />
              <p>{currType}赛事在线看</p>
            </h1>
            <div className={styles.selectBox}>
              {classifyType?.map((item, index) => {
                return (
                  <div
                    key={index}
                    className={cm(styles.cTypeItem, 'textEllipsis', {
                      [styles.typeItemActive]: item?.id == currTypeInfo?.competitionId
                    })}
                    onClick={() => onSelectChange(item)}
                  >
                    {item?.name}
                  </div>
                )
              })}
            </div>
          </div>
          <div className={styles.calendar}>
            <div className={styles.calendarClick}>
              <img loading="lazy" src="/images/date.png" alt="日历" />
              <span>日历</span>
            </div>
            <Calendar className={styles.calendarItem} dateList={dateList} onChange={dateChange} />
          </div>
        </div>

        <div className={styles.main}>
          <div className={cm(styles.commHotRace, 'hideWhenPc')}>
            <p className={styles.hTitle}>热门赛事</p>
            <div className={styles.hotBox}>
              {HOT_RACE_ARR.map((item, index) => {
                return (
                  <Link href={`/sports/${item.url}`} key={index} className={styles.item}>
                    <img loading="lazy" src={item.icon} alt={item.name} />
                    <span>{item.name}</span>
                  </Link>
                )
              })}
            </div>
            <div className={styles.allRace} onClick={() => setRaceALl(true)}>
              <span>全</span>
              <span>部</span>
              <span>赛</span>
              <span>程</span>
            </div>
          </div>
          <div className={cm(styles.phoneDesc, 'hideWhenPc')}>
            <h1 className={styles.left}>{currTypeInfo.competitionName || currType + '赛事在线看'}</h1>
            <p className={styles.right} onClick={() => setSHowPhoneDesc(true)}>
              {currTypeInfo?.competitionName ? (
                <>
                  <span>赛事详情</span>
                  <img loading="lazy" src="/images/phone_arrow.png" alt="手机" />
                </>
              ) : null}
            </p>
            <div className={cm(styles.descPhoneMask, 'hideWhenPc', showPhoneDesc ? styles.showBox : '')}>
              <div className={styles.phoneDescBox}>
                <img
                  loading="lazy"
                  src="/images/close.png"
                  alt="关闭"
                  className={styles.close}
                  onClick={() => setSHowPhoneDesc(false)}
                />
                <p className={styles.title}>赛事详情</p>
                <p className={styles.content}>{desc}</p>
              </div>
            </div>
          </div>
          <div className={styles.mainLeft} ref={parentRef}>
            <Loading isLoading={isLoadData} className={cm(styles.loading, !isLoadData ? styles.loadNull : '')} />
            {listData?.map((item, index) => {
              if (!item.matchList?.length) {
                return null
              }
              return (
                <ProgramItem
                  data={item}
                  key={index}
                  today={currDay}
                  onLogin={() => setShowLogin(true)}
                  onSuccess={updateListData}
                />
              )
            })}
            <Loading isLoading={isLoadData} className={styles.loading} />
          </div>
          <div className={cm(styles.mainRight, 'hideWhenPhone')}>
            <div className={styles.moreProject}>
              <p className={styles.title}>更多项目</p>
              <div className={styles.projectBox}>
                {project?.map((item, index) => {
                  return (
                    <Link
                      href={`/sports/${urlMatch[item.name]}`}
                      key={index}
                      className={cm(styles.projectItem, {
                        [styles.projectItemActive]: currType == item.name
                      })}
                    >
                      <img loading="lazy" src={`/images/sports/${urlMatch[item.name]}.png`} alt={item.name} />
                      <span>{item.name}</span>
                    </Link>
                  )
                })}
              </div>
            </div>
            <div className={styles.hotRace}>
              <p className={styles.title}>热门赛事</p>
              <div className={styles.projectBox}>
                {shuffleHots?.map((item, index) => {
                  return (
                    <Link href={`/sports/${item.url}`} key={index} className={styles.projectItem}>
                      <img loading="lazy" src={item.icon} alt={item.name} />
                      <span className="textEllipsis">{item.name}</span>
                    </Link>
                  )
                })}
              </div>
            </div>
            <div className={styles.raceDesc} style={{ display: isFirstPath ? 'none' : 'flex' }}>
              <div className={styles.title}>赛事简介</div>
              <p className={styles.desc}>{desc}</p>
            </div>
          </div>
        </div>
      </div>

      <div className={cm(styles.allRaceMaskBox, 'hideWhenPc', showRaceAll ? styles.showBox : '')}>
        <div className={styles.allRaceBox}>
          <div className={styles.close}>
            <img loading="lazy" src="/images/close.png" alt="关闭" onClick={() => setRaceALl(false)} />
          </div>
          <div className={styles.box}>
            {allRaceArr.map((item, index) => {
              return (
                <div key={index} className={styles.raceItem}>
                  <div className={styles.title}>
                    <img loading="lazy" src={item.icon} alt={item.name} />
                    <span>{item.name}</span>
                  </div>
                  <div className={styles.raceItemBox}>
                    <Link
                      href={`/sports/${urlMatch[item.name]}`}
                      onClick={() => setRaceALl(false)}
                      className={cm(
                        styles.itemBoxChild,
                        'textEllipsis',
                        classify == urlMatch[item.name] ? styles.active : ''
                      )}
                    >
                      全部
                    </Link>
                    {item.children.map((child, childIndex) => {
                      return (
                        <Link
                          href={`/sports/${child.url}`}
                          onClick={() => setRaceALl(false)}
                          key={childIndex}
                          className={cm(
                            styles.itemBoxChild,
                            'textEllipsis',
                            classify == child.url ? styles.active : ''
                          )}
                        >
                          {child.competitionName}
                        </Link>
                      )
                    })}
                  </div>
                </div>
              )
            })}
          </div>
        </div>
      </div>
    </Responsive>
  )
}

const urlObj = SPORT_INFO.reduce((final, target) => {
  final[target.url] = target
  return final
}, {})

// 获取当前体育类目名
const getCurrProject = (isFirstPath, classify, urlArr) => {
  if (isFirstPath) {
    return urlObj[classify].name
  }
  return (urlArr.filter(item => item.url == classify).pop() || {})?.projectName
}

// 获取当前体育类目id和赛事类目id
const getCurrType = (isFirstPath, currType, classify, projectList, urlMap) => {
  if (isFirstPath) {
    return {
      projectId: (projectList?.filter(item => item.name == currType).pop() || {})?.id
    }
  }
  const currTypeInfo = urlMap?.filter(item => item.url == classify).pop() || {}
  return currTypeInfo
}

// 生成title和desc
const generateTitleAndDesc = (isFirstPath, urlObj, urlMap, url) => {
  if (isFirstPath) {
    return {
      title: urlObj[url]?.title,
      desc: urlObj[url]?.desc
    }
  }
  const currPath = urlMap.filter(item => item.url == url).pop() || {}
  return {
    title: `${currPath?.competitionName}直播在线看，更多${currPath?.projectName}热门赛事免费观看 - 星视界`,
    desc: `${currPath?.competitionName}直播频道提供免费无广告${currPath?.competitionName}全部赛程直播及回看视频，并提供全赛程时间、比分及赛果查询，查看队伍比赛信息，历史比分和场次回放及未来直播时间，更有app可长期稳定观看！`
  }
}

export async function getServerSideProps({ params }) {
  const { classify } = params
  const resArr = (await Promise.allSettled([getProject({}), getRaceUrlMap({})]))?.map(item => {
    if (item.value.code) {
      return {}
    }
    return item.value?.data || {}
  })
  // urlIdMapping
  const urlMap = (resArr[1]?.urlIdMapping || []).filter(item => item?.url)
  const urlArr = [urlMap.map(item => item.url), SPORTS_PATHS].flat(1)
  // 不在url内，输出404页面
  if (!urlArr.includes(classify)) {
    return { notFound: true }
  }

  const isFirstPath = SPORTS_PATHS.includes(classify)
  const project = resArr[0]?.projectList || []
  const currType = getCurrProject(isFirstPath, classify, urlMap)
  const currTypeInfo = getCurrType(isFirstPath, currType, classify, project, urlMap)
  const fetchParams = {
    projectId: isFirstPath ? currTypeInfo.projectId : undefined,
    competitionId: isFirstPath ? undefined : currTypeInfo.competitionId
  }
  const matchDateRes = await getMatchListByTime(fetchParams)
  // 获取随机热门赛事
  const shuffleHots = getShuffleHots()
  let props = {
    layoutProps: {
      noSomeMetaInfo: false,
      ...generateTitleAndDesc(isFirstPath, urlObj, urlMap, classify),
      url: '/sports'
    },
    isFirstPath,
    classify,
    urlMap,
    project,
    currType,
    currTypeInfo,
    matchDate: matchDateRes?.data?.matchDate || [],
    shuffleHots
  }
  return {
    props
  }
}
